﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data;
using System.Globalization;
using HomeDMSDomain;
using System.Data.Linq;

using System.ComponentModel;
using System.Linq;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Diagnostics;
using System.Threading;
using HomeDmsUtils;
using System.Deployment.Application;
using Microsoft.Win32;
using System.Data.SqlServerCe;

namespace bind_n_find
{

    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        #region private fields

        private BindnFindObjectsDataContext _currentContext;
        private filter_ev_args _filter;

        #endregion //private fields

        #region initialization

        public Window1()
        {
            InitializeComponent();
            _init();
        }

        /// <summary>
        /// Window1 initialization
        /// </summary>
        private void _init()
        {
            try
            {
                // event handler for 'filter_is_set' event (find_ctrl control) - reloads documents according to current filter setting
                find_ctrl1.filter_is_set += new filter_ev_handler(find_ctrl1_filter_is_set);
                _grid.SelectionChanged += new SelectionChangedEventHandler(_grid_SelectionChanged);
                // event handler for 'document_collection_changed' event (new_ctrl control) - reloads documents when something is changed (or new document added) in new_ctrl
                new_ctrl.document_collection_changed += new EventHandler(new_ctrl_document_collection_changed);
            }
            catch (Exception ex)
            {
                BNFTrace.DoTrace(TraceTypes.Error, string.Format("Exception in 'Window1._init': {0}", ex.Message));
            }
        }

        #endregion //initialization

        #region event handlers

        /// <summary>
        /// Event handler for 'document_collection_changed' event (new_ctrl control).
        /// Reloads documents when something is changed (or new document added) in new_ctrl.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        void new_ctrl_document_collection_changed(object sender, EventArgs e)
        {
            _load_data();
        }
 
        /// <summary>
        /// Set current document when selection is changed in grid
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        void _grid_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                if (e.AddedItems != null)
                {
                    if (e.AddedItems.Count > 0)
                    {
                        DataRowView drv = (DataRowView)e.AddedItems[0];
                        if (drv != null)
                        {
                            DataRow dr = drv.Row;
                            if (dr != null)
                            {
                                if (dr.ItemArray != null)
                                {
                                    if (dr.ItemArray.Length > 0)
                                    {
                                        int doc_id = int.Parse(dr.ItemArray[0].ToString());
                                        Properties.Settings.Default.CurrentDocumentID = doc_id;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                BNFTrace.DoTrace(TraceTypes.Error, string.Format("Exception in 'Window1._grid_SelectionChanged': {0}", ex.Message));

            }
        }

        /// <summary>
        /// Event handler for 'filter_is_set' event (find_ctrl control). Set filter and reload documents according to current filter setting.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e">
        /// Current filter setting
        /// </param>

        void find_ctrl1_filter_is_set(object sender, filter_ev_args e)
        {
            _filter = e;
            _load_data();
        }

        /// <summary>
        /// Is fired after window is loaded.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                //add 'find_ctrl' control to view, but don't show it by default
                _show_find_ctrl(false);
                find_ctrl1.Width = _grid.Width;

                //if LastOpenedBase is null, show 'first time' dialog 
                if (string.IsNullOrEmpty(Properties.Settings.Default.LastOpenedBase))
                {
                    if (!_show_first_time_dlg())
                        return;
                }
                else
                {
                    //set window title text 
                    BindnFindObjectsDataContext.CurrentDB = Properties.Settings.Default.LastOpenedBase;
                    Title = "Bind`n`find - " + BindnFindObjectsDataContext.CurrentDB;
                    BNFTrace.DoTrace(TraceTypes.Info, string.Format("Database {0} is opened.", BindnFindObjectsDataContext.CurrentDB));
                    //set current context for Window1 and for find control
                    _currentContext = BindnFindObjectsDataContext.Instance;
                    find_ctrl1.currentContext = _currentContext;
                }

                //load documents 
                _load_data();

                //load MRU list
                _load_MRU_list(true);

                //fill "CultureInfos" list with values 
                Application.Current.Properties["CultureInfos"] = CultureInfo.GetCultures(CultureTypes.AllCultures);
            }
            catch (Exception ex)
            {
                BNFTrace.DoTrace(TraceTypes.Error, string.Format("Exception in 'Window1.Window_Loaded': {0}", ex.Message));

                MessageBox.Show(Window.GetWindow(this), ex.Message, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Information);
            }

        }

        /// <summary>
        /// Show/hide 'find' control
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            try
            {
                _show_find_ctrl((bool)_find_tool.IsChecked);
            }
            catch (Exception ex)
            {
                BNFTrace.DoTrace(TraceTypes.Error, string.Format("Exception in 'Window1.CheckBox_Checked': {0}", ex.Message));

                MessageBox.Show(Window.GetWindow(this), ex.Message, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Information);

            }

        }

        /// <summary>
        /// Show/hide 'find' control
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void _find_tool_Unchecked(object sender, RoutedEventArgs e)
        {
            try
            {
                _show_find_ctrl((bool)_find_tool.IsChecked);
            }
            catch (Exception ex)
            {
                BNFTrace.DoTrace(TraceTypes.Error, string.Format("Exception in 'Window1._find_tool_Unchecked': {0}", ex.Message));

                MessageBox.Show(Window.GetWindow(this), ex.Message, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Information);
            }


        }

        /// <summary>
        /// Call '_resize' when window size is changed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            try
            {
                _resize();
            }
            catch (Exception ex)
            {
                BNFTrace.DoTrace(TraceTypes.Error, string.Format("Exception in 'Window1.Window_SizeChanged': {0}", ex.Message));

                MessageBox.Show(Window.GetWindow(this), ex.Message, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Information);
            }

        }



        /// <summary>
        /// Show/hide 'find' control
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// 
        private void Menu_Find_Checked(object sender, RoutedEventArgs e)
        {
            try
            {
                _show_find_ctrl((bool)Menu_Find.IsChecked);
            }
            catch (Exception ex)
            {
                BNFTrace.DoTrace(TraceTypes.Error, string.Format("Exception in 'Window1.Menu_Find_Checked': {0}", ex.Message));

                MessageBox.Show(Window.GetWindow(this), ex.Message, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Information);
            }

        }

        /// <summary>
        /// Show/hide 'find' control
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void Menu_Find_Unchecked(object sender, RoutedEventArgs e)
        {
            try
            {
                _show_find_ctrl((bool)Menu_Find.IsChecked);
            }
            catch (Exception ex)
            {
                BNFTrace.DoTrace(TraceTypes.Error, string.Format("Exception in 'Window1.Menu_Find_Unchecked': {0}", ex.Message));

                MessageBox.Show(Window.GetWindow(this), ex.Message, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Information);
            }

        }

        /// <summary>
        /// Menu 'new database' clicked, create new database
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Menu_NewDatabase_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (!_create_new_db(_get_new_db_path()))
                {

                }
            }
            catch (Exception ex)
            {
                BNFTrace.DoTrace(TraceTypes.Error, string.Format("Exception in 'Window1.Menu_NewDatabase_Click': {0}", ex.Message));

                MessageBox.Show(Window.GetWindow(this), ex.Message, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Information);
            }

        }

        /// <summary>
        /// MRU menu item is clicked, open recently accessed database
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        void MRU_item_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                MenuItem item = (MenuItem)e.Source;
                if (item != null)
                {
                    string path = item.Tag.ToString();
                    if (!string.IsNullOrEmpty(path))
                    {
                        _open_db(path);
                    }
                }
            }
            catch (Exception ex)
            {
                BNFTrace.DoTrace(TraceTypes.Error, string.Format("Exception in 'Window1.MRU_item_Click': {0}", ex.Message));
                MessageBox.Show(Window.GetWindow(this), ex.Message, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Information);
            }

        }

        /// <summary>
        /// Menu 'open database' clicked, open existing database
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Menu_OpenDatabase_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                _open_db();
            }
            catch (Exception ex)
            {
                BNFTrace.DoTrace(TraceTypes.Error, string.Format("Exception in 'Window1.Menu_OpenDatabase_Click': {0}", ex.Message));

                MessageBox.Show(Window.GetWindow(this), ex.Message, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }
        /// <summary>
        /// Menu 'exit' clicked, exit the application
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Menu_Exit_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                Application.Current.Shutdown();
            }
            catch (Exception ex)
            {
                BNFTrace.DoTrace(TraceTypes.Error, string.Format("Exception in 'Window1.Menu_Exit_Click': {0}", ex.Message));
            }
        }

        /// <summary>
        /// Menu 'preferences' clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void Menu_Preferences_Click(object sender, RoutedEventArgs e)
        {
            // TODO: implementation
        }

        /// <summary>
        /// Menu 'New document' clicked, show 'document' dialog in 'new document' mode
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Menu_NewDoc_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                using (new_edit_dlg dlg = new new_edit_dlg(dlg_mode_e.new_t))
                {
                    dlg.Owner = this;
                    dlg.ShowInTaskbar = false;
                    dlg.ShowDialog();
                }
            }
            catch (Exception ex)
            {
                BNFTrace.DoTrace(TraceTypes.Error, string.Format("Exception in 'Window1.Menu_NewDoc_Click': {0}", ex.Message));
            }
        }

        /// <summary>
        /// Menu 'View document' clicked, show 'document' dialog in 'view' mode
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void Menu_ViewDoc_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                using (new_edit_dlg dlg = new new_edit_dlg(dlg_mode_e.view_t))
                {
                    dlg.Owner = this;
                    dlg.ShowInTaskbar = false;
                    dlg.ShowDialog();
                }
            }
            catch (Exception ex)
            {
                BNFTrace.DoTrace(TraceTypes.Error, string.Format("Exception in 'Window1.Menu_ViewDoc_Click': {0}", ex.Message));

            }

        }
        /// <summary>
        /// Menu 'Edit document' clicked, show 'document' dialog in 'edit document' mode
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Menu_EditDoc_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                using (new_edit_dlg dlg = new new_edit_dlg(dlg_mode_e.edit_t))
                {
                    dlg.Owner = this;
                    dlg.ShowInTaskbar = false;
                    dlg.ShowDialog();
                }
            }
            catch (Exception ex)
            {
                BNFTrace.DoTrace(TraceTypes.Error, string.Format("Exception in 'Window1.Menu_EditDoc_Click': {0}", ex.Message));

            }

        }

        /// <summary>
        /// Document is double clicked in grid, show 'document' dialog in 'view' mode
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _grid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            try
            {
                using (new_edit_dlg dlg = new new_edit_dlg(dlg_mode_e.view_t))
                {
                    dlg.Owner = this;
                    dlg.ShowInTaskbar = false;
                    dlg.ShowDialog();
                }
            }
            catch (Exception ex)
            {
                BNFTrace.DoTrace(TraceTypes.Error, string.Format("Exception in 'Window1._grid_MouseDoubleClick': {0}", ex.Message));

            }

        }

        #endregion //event handlers

        #region private member functions

        /// <summary>
        /// Search document in database by document ID
        /// </summary>
        /// <param name="doc_id">
        /// Document ID.
        /// </param>
        /// <returns>
        /// If document is found, return it, otherwise return null.
        /// </returns>
        private Document _doc_by_id(int doc_id)
        {
            try
            {
                foreach (Document doc in _currentContext.Documents)
                {
                    if (doc.document_id == doc_id)
                    {
                        return doc;
                    }
                }
            }
            catch (Exception ex)
            {
                BNFTrace.DoTrace(TraceTypes.Error, string.Format("Exception in 'Window1._doc_by_id': {0}", ex.Message));

            }
            return null;
        }


        /// <summary>
        /// If the application is started for the 1st time, show 'first time' dialog
        /// </summary>
        /// <returns>
        /// Return 'true' if something was chosen in dialog, otherwise return 'false'
        /// </returns>
        private bool _show_first_time_dlg()
        {
            try
            {
                using (first_time_dlg dlg = new first_time_dlg())
                {
                    dlg.ShowInTaskbar = false;
                    dlg.Owner = this;

                    dlg.ShowDialog();
                    if (dlg.DialogResult.HasValue && dlg.DialogResult.Value)
                    {
                        return true;
                    }

                }
            }
            catch (Exception ex)
            {
                BNFTrace.DoTrace(TraceTypes.Error, string.Format("Exception in 'Window1._show_first_time_dlg': {0}", ex.Message));

            }
            return false;
        }


        /// <summary>
        /// Load/reload documents data in grid
        /// </summary>
        private void _load_data()
        {
            try
            {

                //  Text = "Bind`n`find - " + BindnFindObjectsDataContext.CurrentDB;
                _currentContext = BindnFindObjectsDataContext.Instance;
                find_ctrl1.currentContext = _currentContext;

                // create new Datatable object to store documents data
                DataTable dt = new DataTable();
                dt.Columns.Add("Doc_Id");
                dt.Columns.Add("Name");
                dt.Columns.Add("EnteredOn");
                dt.Columns.Add("Keywords");
                dt.Columns.Add("Description");

                foreach (Document doc in _currentContext.Documents)
                {
                    bool add_doc1 = false;
                    bool add_doc2 = false;
                    //check filters first, if no filter is set, add all documents to grid
                    if (_filter != null)
                    {
                        if (!string.IsNullOrEmpty(_filter.tag))
                        {
                            if (doc.Keywords.Contains(_filter.tag))
                            {
                                add_doc1 = true;
                            }
                        }
                        if (!string.IsNullOrEmpty(_filter.description))
                        {
                            if (doc.Description.Contains(_filter.description) || doc.Name.Contains(_filter.description))
                            {
                                add_doc2 = true;
                            }
                        }
                        if (_filter.condition == and_or_e.and_t && add_doc1 && add_doc2 ||
                            _filter.condition == and_or_e.or_t && (add_doc1 || add_doc2))
                        {
                            dt.Rows.Add(new object[] { doc.document_id, doc.Name, doc.EnteredOn, doc.Keywords, doc.Description });
                            BNFTrace.DoTrace(TraceTypes.Info,string.Format("Document added to view: {0}", doc.Name));

                        }
                    }
                    else
                    {
                        dt.Rows.Add(new object[] { doc.document_id, doc.Name, doc.EnteredOn, doc.Keywords, doc.Description });
                        BNFTrace.DoTrace(TraceTypes.Info, string.Format("Document added to view: {0}", doc.Name));

                    }
                }



                DataSet ds = new DataSet("Table");

                ds.Tables.Add(dt);

                //set data context for grid
                _grid.DataContext = ds.Tables[0].DefaultView;
                _grid.SelectedIndex = 0;

                
            }
            catch (Exception ex)
            {
                string mes = ex.Message + Environment.NewLine + "Caught in _load_data().";
                throw new Exception(mes);
            }

        }


        /// <summary>
        /// Show/hide 'find' control which allows to set filters and search for documents using those filters
        /// </summary>
        /// <param name="show">
        /// Show or hide 'find' control
        /// </param>
        private void _show_find_ctrl(bool show)
        {
            try
            {
                if (!show)
                {
                    find_ctrl1.Visibility = Visibility.Collapsed;
                    Menu_Find.Header = Properties.Resources.Menu_Find1;
                    if ((bool)_find_tool.IsChecked) _find_tool.IsChecked = false;
                    if (Menu_Find.IsChecked) Menu_Find.IsChecked = false;
                }
                else
                {
                    find_ctrl1.Visibility = Visibility.Visible;
                    Menu_Find.Header = Properties.Resources.Menu_Find2;
                    if (!(bool)_find_tool.IsChecked) _find_tool.IsChecked = true;
                    if (!Menu_Find.IsChecked) Menu_Find.IsChecked = true;
                    find_ctrl1.currentContext = _currentContext;
                }

                _resize();
            }
            catch (Exception ex)
            {
                string mes = ex.Message + Environment.NewLine + "Caught in _show_find_ctrl().";
                throw new Exception(mes);
            }
            
        }

        /// <summary>
        /// Resize view, set controls sizes when window is resized or some controls are hidden or shown
        /// </summary>

        private void _resize()
        {
            try
            {
                double height = this.Height - menu1.Height - toolBar1.Height - _grid.Margin.Bottom - _grid.Margin.Top;
                if (height > 0) _grid.Height = height;
                if (find_ctrl1.IsVisible)
                {
                    double new_height = _grid.Height - (find_ctrl1.Height + find_ctrl1.Margin.Top + find_ctrl1.Margin.Bottom);
                    if (new_height > 0) _grid.Height = new_height;
                }
            }
            catch (Exception ex)
            {
                string mes = ex.Message + Environment.NewLine + "Caught in _resize().";
                throw new Exception(mes);
            }
        }

        
        /// <summary>
        /// Show 'save file' dialog 
        /// </summary>
        /// <returns>
        /// New database path
        /// </returns>
        private string _get_new_db_path()
        {
            try
            {
                SaveFileDialog dlg = new SaveFileDialog();
                dlg.FileName = "Bind`n`find.sdf";
                dlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                dlg.Filter = Properties.Resources.New_DB_Dlg_Filter;
                dlg.Title = Properties.Resources.New_DB_Dlg_Title;
                Nullable<bool> result = dlg.ShowDialog(this);

                if (result == true)
                {
                    // Save document
                    return dlg.FileName;
                }
            }
            catch (Exception ex)
            {
                string mes = ex.Message + Environment.NewLine + "Caught in _get_new_db_path().";
                throw new Exception(mes);
            } 
            return string.Empty;

        }


        /// <summary>
        /// Create new database 
        /// </summary>
        /// <param name="path">
        /// Path to database 
        /// </param>
        /// <returns>
        /// 'true' if a database was created successfully, otherwise 'false'
        /// </returns>

        private bool _create_new_db(string path)
        {
            try
            {
                if (string.IsNullOrEmpty(path))
                    return false;
                BindnFindObjectsDataContext.CurrentDB = path;
                Title = Properties.Resources.Application_Name + " - " + BindnFindObjectsDataContext.CurrentDB;
                _currentContext = BindnFindObjectsDataContext.Instance;
                find_ctrl1.currentContext = _currentContext;
                try
                {
                    _currentContext.CreateDatabase();
                }
                catch (SqlCeException e)
                {
                    if (e.NativeError != 25501)
                    {
                        MessageBox.Show(Window.GetWindow(this), e.Message, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Information);
                        return false;
                    }
                }
                _currentContext.PrefillDatabaseWithData();

                //set last opened databse path to current
                Properties.Settings.Default.LastOpenedBase = path;
                //add path to MRU if not found in MRU
                _check_MRU(path);
                Properties.Settings.Default.Save();

                //reload documents
                _load_data();
                return true;


            }
            catch (Exception ex)
            {
                string mes = ex.Message + Environment.NewLine + "Caught in _create_new_db().";
                throw new Exception(mes);
            }
            return false;

        }

        /// <summary>
        /// Create collection to save MRU list if it is null
        /// </summary>
        /// <returns></returns>
        private bool _create_MRU_list_array()
        {
            if (Properties.Settings.Default.RecentFilesList == null)
            {
                Properties.Settings.Default.RecentFilesList = new System.Collections.Specialized.StringCollection();
                return true;
            }
            return false;

        }

        /// <summary>
        /// Add new MRU item to MRU list if it was not found in the list
        /// </summary>
        /// <param name="path">
        /// new MRU path item
        /// </param>
        private void _check_MRU(string path)
        {
            try
            {
                bool just_created = _create_MRU_list_array();

                if (!Properties.Settings.Default.RecentFilesList.Contains(path))
                {
                    // if 'path' is not found, add it to MRU list
                    Properties.Settings.Default.RecentFilesList.Add(path);
                    Properties.Settings.Default.Save();
                }
                int capasity = Properties.Settings.Default.MRU_List_Capasity;
                int count = Properties.Settings.Default.RecentFilesList.Count;
                //if MRU items count is greater than capasity, remove 1st item
                if (count > capasity)
                {
                    Properties.Settings.Default.RecentFilesList.RemoveAt(0);
                    Properties.Settings.Default.Save();
                }
                //reload MRU list menus
                _load_MRU_list(just_created);
            }
            catch (Exception ex)
            {
                string mes = ex.Message + Environment.NewLine + "Caught in _check_MRU().";
                throw new Exception(mes);
            }


        }

        /// <summary>
        /// Load MRU list from MRU items array
        /// </summary>
        /// <param name="just_created">
        /// If true, add separator to distinguish MRU menu items from others
        /// </param>
        private void _load_MRU_list(bool just_created)
        {
            try
            {
                if (menu1.Items.Count > 1)
                {
                    MenuItem item1 = (MenuItem)menu1.Items[0];
                    if (item1 != null)
                    {
                        int count = item1.Items.Count;
                        int index = count - 2;
                        if (index < 0) return;
                        bool just_created1 = _create_MRU_list_array();
                        if (just_created || just_created1)
                        {
                            //if MRU list is just created, add separator
                            item1.Items.Insert(index, new Separator());
                            index++;
                        }

                        foreach (string item in Properties.Settings.Default.RecentFilesList)
                        {
                            //if the item exists in menu, don't add it, otherwise insert new item
                            MenuItem s_menu_item = _menu_item_exists(item1.Items, item);
                            if (s_menu_item != null)
                                continue;

                            MenuItem new_item = new MenuItem();
                            new_item.Name = "Menu_MRU_" + index.ToString();
                            new_item.AllowDrop = false;
                            new_item.Header = item;
                            new_item.Tag = item;
                            new_item.Click += new RoutedEventHandler(MRU_item_Click);
                            item1.Items.Insert(index, new_item);
                            index++;
                        }

                        //refresh MRU menu: remove from menu MRU items not existing in MRU array
                        _refresh_MRU_collection(item1.Items);


                    }
                }
            }
            catch (Exception ex)
            {
                string mes = ex.Message + Environment.NewLine + "Caught in _check_MRU().";
                throw new Exception(mes);
            }

        }

        /// <summary>
        /// Check if item with current tag exists in menu items collection
        /// </summary>
        /// <param name="items">
        /// Menu items collection
        /// </param>
        /// <param name="tag">
        /// String tag to check
        /// </param>
        /// <returns>
        /// Returns MenuItem is exists, otherwise null
        /// </returns>
        private MenuItem _menu_item_exists(ItemCollection items, string tag)
        {
            try
            {
                foreach (object itemobj in items)
                {
                    if (!(itemobj is MenuItem))
                        continue;
                    MenuItem item = (MenuItem)itemobj;
                    if (item != null)
                    {
                        if (item.Tag != null)
                        {
                            if (item.Tag.ToString() == tag)
                            {
                                return item;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                string mes = ex.Message + Environment.NewLine + "Caught in _menu_item_exists().";
                throw new Exception(mes);
            }

            return null;
        }

        /// <summary>
        /// Refresh MRU menu: remove from menu MRU items not existing in MRU array
        /// </summary>
        /// <param name="items">
        /// Menu items collection (MRU menu)
        /// </param>
        private void _refresh_MRU_collection(ItemCollection items)
        {
            try
            {
                int count = items.Count;
                for (int i = count - 1; i >= 0; --i)
                {
                    object itemobj = items[i];
                    if (!(itemobj is MenuItem))
                        continue;
                    MenuItem item = (MenuItem)itemobj;
                    if (item != null)
                    {
                        if (item.Tag != null)
                        {
                            bool found = false;
                            foreach (string str in Properties.Settings.Default.RecentFilesList)
                            {

                                if (item.Tag.ToString() == str)
                                {
                                    found = true;
                                    break;
                                }
                            }
                            // remove item from menu if it was not found in MRU items collection
                            if (!found) items.Remove(itemobj);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                string mes = ex.Message + Environment.NewLine + "Caught in _refresh_MRU_collection().";
                throw new Exception(mes);
            }
        }



        
        /// <summary>
        /// Open existing database, showing 'Open file' dialog
        /// </summary>
        private void _open_db()
        {
            try
            {
                OpenFileDialog dlg = new OpenFileDialog();
                dlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                dlg.Filter = Properties.Resources.Open_DB_Dlg_Filter;

                Nullable<bool> result = dlg.ShowDialog(this);
                if (result == true)
                {
                    _open_db(dlg.FileName);
                }
            }
            catch (Exception ex)
            {
                string mes = ex.Message + Environment.NewLine + "Caught in _open_db().";
                throw new Exception(mes);
            }

        }

        /// <summary>
        /// Open existing database
        /// </summary>
        /// <param name="path">
        /// database file path
        /// </param>
        private void _open_db(string path)
        {
            try
            {
                BindnFindObjectsDataContext.CurrentDB = path;
                Title = Properties.Resources.Application_Name + " - " + BindnFindObjectsDataContext.CurrentDB;
                _currentContext = BindnFindObjectsDataContext.Instance;
                find_ctrl1.currentContext = _currentContext;
                _load_data();
                Properties.Settings.Default.LastOpenedBase = path;
                _check_MRU(path);
                Properties.Settings.Default.Save();
            }
            catch (Exception ex)
            {
                string mes = ex.Message + Environment.NewLine + "Caught in _open_db().";
                throw new Exception(mes);
            }
        }

        
    }

    #endregion //private member functions

     #region collection classes definitions
    /// <summary>
    /// Container for 'CultureInfo' items
    /// </summary>
    class CultureInfos
    {
        public CultureInfo[] culture_infos = null;

    }

    /// <summary>
    /// Container for 'image_text_item_template' items 
    /// </summary>
    class BitmapImagesList
    {
        public List<image_text_item_template> bi_list = new List<image_text_item_template>();
    }

    #endregion //collection classes definitions


}
